#pragma once

#include<iostream>
#include<unistd.h>
#include<sys/socket.h>
#include<string>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<cstring>
#include<signal.h>
#include<pthread.h>
#include"ThreadPool.hpp"
#include"Task.hpp"

using namespace std;

#define BACKLOG 5;
#define DEFAULT_PORT 8081

// class Para {
// public:
//     Para(int sock, string ip, int port) : _sock(sock), _ip(ip), _port(port){}

//     int _sock;
//     string _ip;
//     int _port;
// };

class TcpServer {
    public:
        TcpServer(int port = DEFAULE_PORT) : _port(port), _listen_sockfd(-1), _tp(nullptr) {}

        bool InitTcpServer() {
            //创建监听套接字文件
            _listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
            if (_listen_sockfd < 0) {
                perror("socket");
                return false;
            }

            //设置当前套接字信息
            struct sockaddr_in local;
            memset(&local, 0, sizeof(local));
            local.sin_family = AF_INET;
            local.sin_port = htons(_port);    //从主机序列转为网络序列（因为要向网络上发送）
            local.sin_addr.s_addr = INADDR_ANY;

            //进行绑定
            if (bind(_listen_sockfd, (struct sockaddr*)&local, sizeof(local)) < 0) {
                perror("bind");
                return false;
            }

            //监听是否有新链接
            if (listen(_listen_sockfd, BACKLOG) < 0) {
                perror("listen");
                return false;
            }

            _tp = new ThreadPool<Task>();

            return true;
        }

        // static void* HanderReuqest(void* arg) {
        //     pthread_detach(pthread_self());
        //     Para* p = (Para*)arg;
            
        //     Service(p->_sock, p->_ip, p->_port);
        //     delete p;
        // }

        void Loop() {
            while (true) {
                struct sockaddr_in peer;
                socklen_t len = sizeof(peer);
                int sock = accept(_listen_sockfd, (struct sockaddr*)&peer, &len);
                if (sock < 0) {
                    perror("accept");
                    continue;
                }

                string ip = inet_ntoa(peer.sin_addr);
                int port = ntohs(peer.sin_port);

                Task t(sock, ip, port);
                _tp->Push(t);
                
                // Para* p = new Para(sock, ip, port);
                // pthread_t tid;
                // pthread_create(&tid, nullptr, HanderRequest, p);
            }
        }

        // static void Service(int sock, string ip, int port) {
        //     char buf[1024];
        //     while (true) {
        //         ssize_t size = read(sock, buf, sizeof(buf) - 1);
        //         if (size > 0) {
        //             buf[size] = 0;  
        //             cout << ip << "&" << port << ":" << buf << endl;
        //             write(sock, buf, size);
        //         }
        //         else if(size == 0) {
        //             cout << ip << "&" << port << " close!" << endl;
        //             break;
        //         }
        //         else {
        //             perror("read");
        //             break;
        //         }
        //     }
        //     close(sock);
        //     cout << "Service done!" << endl;
        // }
        ~TcpServer() {
            if (_listen_sockfd > 0) {
                close(_listen_sockfd);
            }
            if (_tp) {
                delete _tp;
            }
        }

    private:
        int _listen_sockfd;
        int _port;
        ThreadPool<Task>* _tp;
};